import { ReactiveProperty } from '../../libs/rxjs/cc3/ReactiveProperty';
import { concat, map, Observable, of, Subscription, defer } from 'rxjs';
import { _decorator, Component, Node, director, System, Eventify, log, js, sys } from 'cc';
import { nullifySubscription } from '../../libs/rxjs/utils';
import { DevConfig } from '../../managers/DevConfig';
import { i18n } from '../../i18n';
const { ccclass, property } = _decorator;

const ByDanceRewardAdUnitId = "11a592kok8g620k6b1"; //"8h62kmlf1d4k1fkobe"; //hard版
const ByDanceRewardAdUnitId2 = "fjde1jc8k08dhc36q5";

const ByDanceInterstitialUnitId = ""; //抖音插屏广告位id

@ccclass('ByteDanceVideoAdManager')
class ByteDanceVideoAdManager extends Eventify(System) {

    public static instance: ByteDanceVideoAdManager;
    static ID = 'bytedance_system';

    registerSystem() {
        director.unregisterSystem(director.getSystem(ByteDanceVideoAdManager.ID));
        director.registerSystem(ByteDanceVideoAdManager.ID, bdadm, System.Priority.MEDIUM);
        bdadm.init();
    }

    init() {
        log(`<${js.getClassName(this)}>`, 'init');

        if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
            this.ByteDanceVideoAdInit();
        }
    }

    running: ReactiveProperty<boolean> = new ReactiveProperty<boolean>().init(false);

    showAds(): Observable<boolean> {
        if (this.running.value) {
            return of(null);
        } else {
            return new Observable(observer => {
                if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME && !DevConfig.adFakeProcess) {
                    this.running.value = true;
                    bdadm.videoAdInit(() => {
                        this.running.value = false;
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        observer.next(true);
                        observer.complete();
                    }, () => {
                        this.running.value = false;
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        observer.next(false);
                        observer.complete();
                    });
                    bdadm.ByteDanceVideoAdShow();
                } else {
                    this.running.value = true;

                    // globalThis.GameManager.instance.frontTipShow('广告替代流程，返回成功').subscribe();
                    globalThis.GameManager.instance.frontTipShow(i18n.t('f.adholder')).subscribe();

                    setTimeout(() => {
                        this.running.value = false;
                        observer.next(true);
                        observer.complete();
                    }, 500);
                }
            });
        }
    }

    private videoAdInit(success, failed) {
        this.callBackSuccess = success;
        this.callBackFailed = failed;
    }

    private callBackSuccess: any = null;     //成功播放回调函数
    private callBackFailed: any = null;      //失败播放回调函数
    private rewardedVideoAd: any = null;     //激励广告实例

    //广告成功播放结束
    private videoAdSuccess() {
        if (this.callBackSuccess != null) {
            this.callBackSuccess.call(this);
        }
    }
    //广告播放失败（提前关闭）
    private videoAdFailed() {
        if (this.callBackFailed != null) {
            this.callBackFailed.call(this);
        }
    }

    /**
     * 抖音广告插件
     */
    public ByteDanceVideoAdInit() {

        console.log("抖音广告组件初始化");
        let self = this;

        this.rewardedVideoAd = globalThis.tt.createRewardedVideoAd({
            adUnitId: DevConfig.hard ? ByDanceRewardAdUnitId : ByDanceRewardAdUnitId2,                           //广告位 id，后续可以在平台基于广告位id看数
            // multiton: true,                                  //是否开启再得广告模式（只支持安卓系统的抖音和抖音极速版）
            // multitonRewardedMsg: "观看下一个可领取更多奖励",   //再得广告的奖励文案，玩家每看完一个广告都会展示，如【再看1个获得xx】xx就multitonRewardMsg中的文案，按顺序依次展示，单个文案最大长度为 7multiton为true时必填
            // multitonRewardTimes:5,                           //额外观看广告的次数，合法的数据范围为1-4，multiton为true时必填
            // progressTip:false,                               //是否开启进度提醒，开启时广告文案为【再看N个获得xx】，关闭时为【 再看1个获得xx】。N表示玩家当前还需额外观看广告的次数。
        });

        //监听错误信息
        this.rewardedVideoAd.onError(function (res) {
            console.log("播放广告失败:", res.errCode, res.errMsg);
        });

        //
        this.rewardedVideoAd.onClose(function (res) {
            console.log("播放广告结束:", res);
            if (res.isEnded) {
                console.log("播放广告结束,可以领取奖励");
                //  self.callBackSuccess.call(this);
                self.videoAdSuccess();
            } else {
                console.log("播放广告结束,不可以领取奖励");
                self.callBackFailed.call(this);
                self.videoAdFailed();
            }
        });
    }

    public ByteDanceVideoAdLoad() {
        this.rewardedVideoAd.load().then(() => {
            console.log("手动独立加载成功");
        });
    }

    public ByteDanceVideoAdShow() {
        let self = this;

        //手动加载广告
        // this.rewardedVideoAd.load().then(() => {
        //     console.log("手动加载成功");
        //     this.rewardedVideoAd.show();
        // });

        //广告展示
        this.rewardedVideoAd.show().then(() => {
            console.log("视频广告展示");
        }).catch((err) => {
            console.log("广告组件出现问题", err);
            // 可以手动加载一次
            self.rewardedVideoAd.load().then(() => {
                console.log("手动加载成功");
                // 加载成功后需要再显示广告
                self.rewardedVideoAd.show();
            });
        });
    }

    // InterstitiaAd
    private interstitiaAd: any = null;     //激励广告实例
    firstLaunchTs: number = null;
    lastVideoAdTs: number = null;
    interstitia_running = false;

    interstitialLimitDate = new Date('2023/03/26 00:00:00');
    isOverLimitDate() { // true 开始加广告，false 跳过广告
        return new Date().valueOf() - this.interstitialLimitDate.valueOf() >= 0;
    }

    isTimeEnough() {
        return true; // 去除间隔时间限制
        let curTs = Date.parse(new Date().toString()) / 1000;
        let lastTs = this.lastVideoAdTs / 1000;
        if (curTs - lastTs < 60) {
            console.log("上一次播放广告时间戳：", lastTs, " 当前时间戳：", curTs, " 相差：", curTs - lastTs)
            return false;
        }
        return true;
    }

    firstLaunchEnough() {
        return true; // 去除首次时间限制
        let curTs = Date.parse(new Date().toString()) / 1000;
        let lastTs = this.firstLaunchTs / 1000;
        if (curTs - lastTs < 30) {
            console.log("游戏启动时间：", lastTs, " 当前时间戳：", curTs, " 相差：", curTs - lastTs)
            return false;
        }
        return true;
    }

    _interstitia_sub: Subscription = null;
    public showInterstitial(callback: (result) => void, onShow: () => void) {
        if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
            if (this.interstitia_running) {
                callback(false);
                return false;
            }
            if (!this.isOverLimitDate()) {
                return false;
            }
            if (!this.firstLaunchEnough()) {
                callback(false);
                return false;
            }
            if (!this.isTimeEnough()) {
                callback(false);
                return false;
            }
            nullifySubscription.call(this, '_interstitia_sub');
            if (this.interstitiaAd != null) this.interstitiaAd.destroy();
            this._interstitia_sub = concat(
                of(null).pipe(map(_ => {
                    this.interstitia_running = true;
                    this.interstitiaAd = globalThis.tt.createInterstitialAd({
                        adUnitId: ByDanceInterstitialUnitId
                    });
                    this.interstitiaAd.onError((err) => {
                        console.error("插屏广告报错", err, err.errCode, err.errMsg);
                        this.interstitia_running = false;
                        callback(false);
                    })
                    this.interstitiaAd.onClose(() => {
                        console.log("插屏广告关闭");
                        this.lastVideoAdTs = Date.parse(new Date().toString());
                        this.interstitia_running = false;
                        callback(true);
                    })
                })),
                defer(() => this.interstitialOnLoadObserve(this.interstitiaAd)),
                defer(() => new Observable(observer => {
                    this.interstitiaAd.show().then(() => {
                        console.log("插屏广告 展示成功");
                        onShow();
                        observer.next('success');
                        observer.complete();
                    }).catch((err) => {
                        console.error("插屏广告组件出现问题", err);
                    });
                }))
            ).subscribe();
        } else {
            globalThis.GameManager.instance.frontTipShow('插屏替代流程，返回成功').subscribe();
            onShow();
            callback(true);
        }
    }

    public destroyInterstitial() {
        nullifySubscription.call(this, '_interstitia_sub');
        if (this.interstitiaAd == null) {
            console.error("没有创建插屏广告实例");
            return;
        } else {
            this.interstitiaAd.destroy();
            this.interstitiaAd = null;
        }
    }

    public interstitialOnLoadObserve(interstitiaAd) {
        return new Observable(observer => {
            let onLoadHandle = () => {
                console.log("插屏广告加载成功");
                observer.next(null);
                observer.complete();
            };
            interstitiaAd.onLoad(onLoadHandle);
            return () => {
                // interstitiaAd.destroy();
            }
        });
    }
}

globalThis.ByteDanceVideoAdManager = ByteDanceVideoAdManager;

export const bdadm = ByteDanceVideoAdManager.instance = new ByteDanceVideoAdManager();